﻿using System;
using System.Windows.Media;
using System.Windows.Media.Media3D;

using SBPweb.Presentation.CompleteMesh.Utils;

namespace SBPweb.Presentation.CompleteMesh.Primitives
{
    public class SphereMesh : RoundMesh
    {

        #region Constructor logic

        public SphereMesh()
            :base()
        {
            pTextureCoordinateGeometry = Textures.TextureCoordinateGeometries.Spherical;
        }

        #endregion

        #region Overridden methods

        protected override void CalculateGeometry()
        {
            int e;
            double segmentRad = Math.PI / 2 / (pN + 1);
            int numberOfSeparators = 4 * pN + 4;

            InitializeCollections();

            // vertexes
            for (e = -pN; e <= pN; e++)
            {
                double r_e = pR * Math.Cos(segmentRad * e);
                double y_e = pR * Math.Sin(segmentRad * e);

                for (int s = 0; s <= (numberOfSeparators - 1); s++)
                {
                    double z_s = r_e * Math.Sin(segmentRad * s) * (-1);
                    double x_s = r_e * Math.Cos(segmentRad * s);
                    pMesh.Positions.Add(new Point3D(x_s, y_e, z_s));
                }
            }
            pMesh.Positions.Add(new Point3D(0, pR, 0));
            pMesh.Positions.Add(new Point3D(0, -1 * pR, 0));

            // triangles
            for (e = 0; e < 2 * pN; e++)
            {
                for (int i = 0; i < numberOfSeparators; i++)
                {
                    pMesh.TriangleIndices.Add(e * numberOfSeparators + i);
                    pMesh.TriangleIndices.Add(e * numberOfSeparators + i + numberOfSeparators);
                    pMesh.TriangleIndices.Add(e * numberOfSeparators + (i + 1) % numberOfSeparators + numberOfSeparators);

                    pMesh.TriangleIndices.Add(e * numberOfSeparators + (i + 1) % numberOfSeparators + numberOfSeparators);
                    pMesh.TriangleIndices.Add(e * numberOfSeparators + (i + 1) % numberOfSeparators);
                    pMesh.TriangleIndices.Add(e * numberOfSeparators + i);
                }
            }

            for (int i = 0; i < numberOfSeparators; i++)
            {
                pMesh.TriangleIndices.Add(e * numberOfSeparators + i);
                pMesh.TriangleIndices.Add(e * numberOfSeparators + (i + 1) % numberOfSeparators);
                pMesh.TriangleIndices.Add(numberOfSeparators * (2 * pN + 1));
            }

            for (int i = 0; i < numberOfSeparators; i++)
            {
                pMesh.TriangleIndices.Add(i);
                pMesh.TriangleIndices.Add((i + 1) % numberOfSeparators);
                pMesh.TriangleIndices.Add(numberOfSeparators * (2 * pN + 1) + 1);
            }

            // textures
            ApplyTextureCoordinates();
        }

        #endregion

    }
}